﻿using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using UnityStandardAssets.ImageEffects;

namespace Battle
{
    [RequireComponent( typeof( UltimateData ) )]
    public class UltimateLogic :MonoBehaviour
    {
        public UltimateData data;
        public float currentTime;
        public float totalTime;
        public bool needControlFovs;
        public bool needControlActors;

        public float previewFov;
        public float previewPointTime;
        public float nextFov;
        public float nextPointTime;

        public GameObject textureEffect;

        #region Component
        void OnEnable()
        {
            if(StaticData.currentSceneType != SceneType.BATTLE)
            {
                return;
            }
            if( data==null )
            {
                data = GetComponent<UltimateData>();
            }

            currentTime = 0f;

            //Fov module
            needControlFovs = data.fovControllers.Count > 0;
            if( needControlFovs )
            {
                data.fovControllers.Sort( ( lh, rh ) =>
                {
                    return lh.keyframeOrTime > rh.keyframeOrTime ?1:-1;
                } );
            }

            //Actor module
            needControlActors = data.showOrHiddenControllers.Count > 0;
            if( needControlActors )
            {
                data.showOrHiddenControllers.Sort( ( lh, rh ) =>
                {
                    return lh.keyframeOrTime > rh.keyframeOrTime? 1:-1;
                } );
            }



            this.totalTime = data.anim.GetClip( data.aniName ).length;

            UnifyTimeUnit();
            InitFirstFov();

            this.trueStartTime = Time.unscaledTime;


            DetailEffect();

            RemoveUILayerFromCameraCullingMask();
            
        }

        void Awake()
        {
            /*
            var _AudioListener = data.cam.GetComponent<AudioListener>();
            if( _AudioListener!=null )
            {
                _AudioListener.enabled = false;
            }
             * */
        }

        void DetailEffect()
        {
            /*if( mainCamMotionBlur == null )
            {
                mainCamMotionBlur = data.cam.gameObject.AddComponent<MotionBlur>();
            }
            if( mainCamMotionBlur!=null ) mainCamMotionBlur.enabled=true;
             * */

            if( mainCamBloom==null )
            {
                mainCamBloom = data.cam.gameObject.GetComponent<BloomOptimized>();
            }
            if( mainCamBloom!=null ) mainCamBloom.enabled=true;

            if(glow==null)
            {
                glow = data.cam.gameObject.GetComponent<Glow11.Glow11>();
            }
            if( glow!=null ) glow.enabled=true;

            if( BattleManager.Instance!=null )
            {
                RenderManager.GetInstance().HideShadow();
            }
        }

        #region this effect
        public MotionBlur mainCamMotionBlur;
        public BloomOptimized mainCamBloom;
        public Glow11.Glow11 glow;
        #endregion


        void OnDisable()
        {
            if (StaticData.currentSceneType != SceneType.BATTLE)
            {
                return;
            }
            StopAllCoroutines();
            if( BattleManager.Instance!=null )
            {
                RenderManager.GetInstance().ShowShadow();
            }
        }

        // Update is called once per frame
        void Update()
        {
            this.currentTime+=Time.deltaTime;

            this.trueDurationTime = Time.unscaledTime - this.trueStartTime;
            this.trueCurrentTime = Time.unscaledTime;

            ControlFov();
            ControlShowOrHidden();
        }
        public float trueStartTime;
        public float trueDurationTime;
        public float trueCurrentTime;

        #endregion

        #region Inner Running Function
        /// <summary>
        /// 统一时间单位
        /// </summary>
        void UnifyTimeUnit()
        {
            if( needControlFovs )
            {
                for( int i=0; i< data.fovControllers.Count; ++i )
                {
                    var it = data.fovControllers[i];
                    it.keyTime = GetTimeUnit( it.keyframeOrTime );
                }
            }

            if( needControlActors )
            {
                for( int i=0; i<data.showOrHiddenControllers.Count; ++i )
                {
                    var it = data.showOrHiddenControllers[i];
                    it.keyTime = GetTimeUnit( it.keyframeOrTime );
                }
            }

            //统一大招时间
            totalTime = GetTimeUnit( data.totalFrameOrTime );
        }



        void InitFirstFov()
        {
            if( needControlFovs )
            {
                previewFov = data.cam.fieldOfView;
            }
        }

        void ControlUltimateFaceChage() {

        }

        void ControlFov()
        {
            if( needControlFovs )
            {
                if( data.fovControllers.Count > 1 )
                {
                    for( int i=0; i<data.fovControllers.Count-1; ++i )
                    {
                        var curIt = data.fovControllers[i];
                        var nextIt = data.fovControllers[i+1];

                        if( curIt.keyTime < currentTime && currentTime<=nextIt.keyTime )
                        {
                            if( data.fovType== UltimateData.FovType._3DMax )
                            {
                                previewFov = Fov_3DMaxToUnity( curIt.fov );
                                nextFov = Fov_3DMaxToUnity( nextIt.fov );
                            }
                            else
                            {
                                previewFov =  curIt.fov;
                                nextFov =  nextIt.fov;
                            }

                            previewPointTime = curIt.keyTime;
                            nextPointTime = nextIt.keyTime;

                            break;
                        }
                    }
                }
                else
                {
                    nextFov = data.fovControllers[0].fov;
                    previewPointTime=0f;
                    nextPointTime = data.fovControllers[0].keyTime;
                }

                CalcCurrentCameraFov();
            }
        }


        void ControlShowOrHidden()
        {
            if( needControlActors )
            {
                foreach( var obj in data.showOrHiddenControllers )
                {
                    if( obj.keyTime < currentTime )
                    {
                        if( obj!=null )
                        {
                            if (!obj.show)
                            {
                                obj.authors.transform.localPosition = new Vector3(10000, 10000, 10000);
                            }
                            else {
                                obj.authors.transform.localPosition = Vector3.zero;
                            }
                            // obj.authors.SetActive( obj.show );
                        }
                        else
                        {
                            throw new Exception( "[EXCEP] obj=null" );
                        }
                    }
                    else
                    {
                        continue;
                    }
                }
            }
        }


        void CalcCurrentCameraFov()
        {
            if( previewFov == nextFov )
            {
                data.cam.fieldOfView = previewFov;
            }
            else
            {
                data.cam.fieldOfView = LerpFov( previewFov, nextFov, previewPointTime, nextPointTime, this.currentTime- this.previewPointTime );
            }
        }
        #endregion

        #region Tool
        float LerpFov( float prevFov, float nextFov, float prevTime, float nextTime, float delayTime )
        {
            return Mathf.Clamp( (nextFov - prevFov) * (delayTime) / (nextTime - prevTime) + (prevFov), prevFov, nextFov );
        }

        float Fov_3DMaxToUnity( float fov )
        {
            return Mathf.Atan( 9 / 16f * Mathf.Tan( fov * 0.5f * Mathf.Deg2Rad ) ) * Mathf.Rad2Deg * 2f;
        }

        float GetTimeUnit( float t )
        {
            if( data.timeType == UltimateData.TimeType.Frame ) return t / 30f;
            if( data.timeType == UltimateData.TimeType.MilliSecond ) return t * 1000f;

            return t;
        }

        public void RemoveUILayerFromCameraCullingMask() {
            int uiLayer = LayerMask.NameToLayer("UI");
            data.cam.cullingMask = data.cam.cullingMask & (~(1 << uiLayer));
        }
        #endregion
    }
}